<?php

namespace App\Services\WechatApi\UnifiedOrder;

use App\Caches\WechatJsapiTicketCache;
use App\Services\ServiceBase;
use App\Services\WechatService;
use YQ\YqCurl;
use YQ\YqExtend;

class JsapiFunc extends ServiceBase
{
    /**
     * 更新微信 jsapi ticket
     * https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#62
     *
     * @return string
     */
    private function updateJsapiTicket($appid, $appsecret)
    {
        $access_token = WechatService::getInstance()->getAccessToken($appid, $appsecret);
        $url          = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$access_token}&type=jsapi";
        $res          = YqCurl::curl($url, false, 0, 1);
        if (!$res) {
            return false;
        }
        $msg = json_decode($res, true);
        if (!isset($msg['ticket'])) {
            return false;
        }

        WechatJsapiTicketCache::getInstance()->update($appid, [
            'jsapi_ticket'         => $msg['ticket'],
            'jsapi_ticket_timeout' => ($msg['expires_in'] + time() - 300),
        ]);

        return $msg['ticket'];
    }

    /**
     * 获取微信 jsapi ticket
     * https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#62
     *
     * @return string
     */
    public function getJsapiTicket($appid, $appsecret)
    {
        $data  = WechatJsapiTicketCache::getInstance()->get($appid);
        if ($data === null || $data['jsapi_ticket_timeout'] < time()) {
            return $this->updateJsapiTicket($appid, $appsecret);
        } else {
            return $data['jsapi_ticket'];
        }
    }

    /**
     * 通过config返回给前端初始化jsapi接口
     * https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
     *
     * @param  array  $apis  需要使用js接口列表
     * @param  bool   $debug 是否为调试模式
     * @param  string $url   当前请求地址
     * @return array
     */
    public function bulidConfig($appid,  $appsecret, array $apis, bool $debug, string $url)
    {
        $jsapi_ticket = $this->getJsapiTicket($appid, $appsecret);
        if (!$jsapi_ticket) {
            return;
        }

        // 注意 URL 一定要动态获取，不能 hardcode.
        $timestamp = time();
        $nonce_str = YqExtend::getRandom();
        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        $string = "jsapi_ticket=$jsapi_ticket&noncestr=$nonce_str&timestamp=$timestamp&url=$url";

        $signature = sha1($string);
        $sign_package = [
            "debug"     => $debug,       // 是否开启debug模式
            "appId"     => $appid,       // 公共号 appid
            "timestamp" => $timestamp,   // 时间戳
            "nonceStr"  => $nonce_str,   // 随机字符串
            "signature" => $signature,   // sha1签名
            "jsApiList" => $apis,        // 需要使用的JS接口列表
        ];

        return $sign_package;
    }

    /**
     * 微信内H5调起支付-网页端接口参数列表
     * https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6
     * @param  string $prepay_id 统一下单接口 unifiedOrder() 返还的 预支付交易会话标识
     * @return array
     */
    public function bridgeConfig($appid, $mch_key, $prepay_id)
    {
        $params = [
            'appId' => $appid,
            'timeStamp' => time(),
            'nonceStr' => YqExtend::uniqid32(),
            'package' => "prepay_id={$prepay_id}",
            'signType' => 'MD5',
        ];
        $params['paySign'] = UnifiedOrder::getInstance()->getSign($mch_key, $params);

        return $params;
    }
}
